﻿
/////////////////////////////////////////////////////////////////
//File: ArticleDao.cs
//Description: 
//Copyright© 2011 Moliu
//History:
//  2011-3-26 18:11:20    CodeSmith5.0.1    Original Version
/////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.SqlTypes;
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Configuration;
using MAF.Common;


namespace MAF.CRUD
{
    public abstract class DatabaseCRUD<T> : ICRUD<T> where T : BaseInfo
    {
        protected ISqlMapper map = null;

        private string _TableName = "";
        protected virtual string _Table
        {
            get { return _TableName; }
            set { _TableName = value; }
        }  

        #region 构造方法

        [Obsolete("此构造方法已不推荐使用")]
        public DatabaseCRUD(string configFile) : this(configFile,null){}

        public DatabaseCRUD(string configFile, string tableName)
        {
            if (string.IsNullOrEmpty(configFile))
            {
                //这样写，配置文件的默认文件名是--sqlmap.config
                map = Mapper.Instance();
            }
            else
            {
                // 这样写，配置文件为指定的文件名
                DomSqlMapBuilder sqlMapBuilder = new DomSqlMapBuilder();
                map = sqlMapBuilder.Configure(configFile);
            }
            _Table = tableName;
        }

        #endregion

        #region 抽象属性
        protected abstract string _MapAdd { get; }
        protected abstract string _MapUpdate { get; }
        protected abstract string _MapDelete { get; }
        protected abstract string _MapSearch { get; }
        protected abstract string _MapCount { get; }
        #endregion

        #region ICRUD<T> 成员

        public virtual void Add(T info)
        {
            info.PersistenceName = _Table;
            map.Insert(_MapAdd, Check(info));
        }

        public virtual void Update(T info)
        {
            info.PersistenceName = _Table;
            map.Update(_MapUpdate, Check(info));
        }

        public virtual int Delete(string ids)
        {
            string[] arry = ids.Split(" ,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            if (0 == arry.Length)
                return 0;

            // 检查数据中是否包含非Guid的数据
            try
            {
                foreach (string s in arry)
                    new Guid(s);
            }
            catch
            {
                throw new ArgumentException("Id中含有非Guid的数据");
            }

            BaseQueryVo vo = CreateQueryVo(null);
            vo.Ids = ids;
            return map.Delete(_MapDelete, vo);
        }

        public virtual T Show(Guid id)
        {
            BaseQueryVo vo = CreateQueryVo(null);
            vo.Id = id.ToString();
            return map.QueryForObject<T>(_MapSearch, vo);
        }

        public virtual IList<T> Index(BaseQueryVo vo)
        {
            vo = CreateQueryVo(vo);

            if (null == vo.Page)
            {
                return map.QueryForList<T>(_MapSearch, vo);
            }
            else
            {
                PageInfo p = vo.Page;
                if (0 == p.RecordCount) { p.RecordCount = Count(vo); }
                int skip = (p.CurrentPage - 1) * p.PageSize;
                int max = p.PageSize;
                return map.QueryForList<T>(_MapSearch, vo, skip, max);
            }
        }

        public virtual int Count(BaseQueryVo vo)
        {
            if (null == vo)
                vo = new BaseQueryVo();

            vo.Table = _Table;
            return map.QueryForObject<int>(_MapCount, vo);
        }

        public BaseQueryVo ParseToQueryVo(NameValueCollection nvc)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Private Method

        private T Check(T info)
        {
            if (DateTime.MinValue == info.CreatedOn)
                info.CreatedOn = DateTime.Parse(SqlDateTime.MinValue.ToString());
            if (DateTime.MinValue == info.ModifiedOn)
                info.ModifiedOn = DateTime.Parse(SqlDateTime.MinValue.ToString());

            return info;
        }

        private BaseQueryVo CreateQueryVo(BaseQueryVo vo)
        {
            if (vo == null)
                vo = new BaseQueryVo();

            vo.Table = _Table;

            return vo;
        }
        #endregion

    }
}